<?php

namespace IDock\Insurance\DAJIA\Request;

use Exception;
use IDock\Insurance\DAJIA\DAJIAEnums;
use IDock\Insurance\DAJIA\Request\AllDAJIARequest;
use IDock\Insurance\DAJIA\Response\CommonResponse;
use IDock\Insurance\DAJIA\Response\InsuranceOrderQueryResponse;
use IDock\Insurance\DAJIA\Response\NonCarUnderWritingResponse;
use IDock\Printer\NonCar\NonCarSubCoveragePrinter;
use IDock\Visitor\NonCar\NonCarInquiryVisitor;
use IDock\Visitor\NonCar\NonCarProductVisitor;
use IDock\Visitor\Premium\PremiumExtInfoVisitor;

/**
 * 非车核保
 */
class NonCarUnderWritingRequest extends AllDAJIARequest
{
    protected $code = 'NVHL-ODR1001';

    protected $response = NonCarUnderWritingResponse::class;

    protected $urlTip = '非车核保接口';

    /**
     * @var PremiumExtInfoVisitor $extVisitor
     */
    public $extVisitor;

    /**
     * @var NonCarInquiryVisitor $visitor
     */
    protected $visitor;

    public function generate(): array
    {
        $param = [
            'bookingNo' => 'GHX' . date('YmdHis') . mt_rand(10000, 99999),
            'ocPlyNo' => $this->visitor->argc['ciInquiryNo'] ?? '',
            'openCoverNo' => $this->visitor->argc['biInquiryNo'] ?? '',
            'signflag' => '1',//核保签单
            'policyInfos' => [[
                'applySeqNo' => '1',
                'base' => $this->getBaseInfo(),
                'applicant' => $this->getApplicant(),
                'insured' => $this->getInsured(),
                'businessInfo' => $this->getBusinessInfo(),
                'prodBaseInfo' => [
                    $this->getProdBaseInfo()
                ]
            ]],
        ];
        /**
         * @var NonCarProductVisitor $plan
         */
        $plan = $plan = $this->visitor->getNonCarList()[0] ?? [];
        foreach ($param['policyInfos'] as &$val){
            if($plan->productCode == '0679'){
                $val['_0679_tgt'] = $this->get0679Tgt();
                $val['_0679_tgtList_1'] = $this->get0679TgtList();
            }else{
                $val['_0684_tgt'] = $this->get0684Tgt();
                $val['_0684_tgtList_1'] = $this->get0684TgtList();
            }
        }

        return $param;
    }

    public function getBaseInfo()
    {
        /**
         * @var NonCarProductVisitor $plan
         */
        $plan = $this->visitor->getNonCarList()[0] ?? [];
        $total = 0;
        /**
         * @var NonCarSubCoveragePrinter $val
         */
        foreach ($plan->subCoverage as $val){
            $total += $val->premium;
        }
        $arr = [
            "goodsCode" => "SP008",//商品号
            "schemeCode" => $plan->planCode,//方案号
            "copies" => 1,//投保份数 默认1份
            "perPrm" => $total,//单份方案保费
            "sumPrm" => round($total * $plan->insuredNum,2),//总保费
            "appTm" => date('Y-m-d H:i:s'),//投保日期
            "effectiveDate" => $this->visitor->startData,//保险起期
            "expireDate" => $this->visitor->endData,//保险止期
            "isImmeffMrk" => date('H:i:s',strtotime($this->visitor->startData)) == '00:00:00' ? '1' : '0',//是否即时起保
            "isGrpMrk" => "0",//是否团单
            "insuredNum" => 1 //被保险人数量
        ];
        return $arr;
    }

    public function getApplicant()
    {
        $applicant = $this->visitor->getApplicantVisitor();
        $arr = [
            "appName" => $applicant->name,//投保人名称
            "appCertfCde" => $applicant->certificateNo,//证件号码
            "appCertfCls" => DAJIAEnums::$certificateTypeCode[$applicant->certificateTypeCode],//证件类型
            "appClntMrk" => DAJIAEnums::$relationTypeCode[$applicant->typeCode],//客户分类/投保人性质
            "appCountry" => "1",//国家
            "appProvince" => $applicant->provinceCode,//省份
            "appCity" => $applicant->cityCode,//市
            "appCounty" => $applicant->areaCode,//县
            "appClntAddr" => $applicant->address,//详细地址
            "appStreet" => $applicant->address,//街道
            "appMobile" => $applicant->mobile,//手机
            "appExpiredFlag" => "false",//证件是否长期有效
            "appEffectiveDate" => $applicant->certificateStartDate,//证件有效起期
            "appExpiredDate" => $applicant->certificateEndDate,//证件失效日期
            "appEmail" => $applicant->email,//邮箱
        ];
        if($applicant->typeCode == 'R1'){
            $arr['appAge'] = $this->getAge($applicant->certificateNo);//年龄
            $arr['appSex'] = $this->getGenderByIDcard($applicant->certificateNo);//性别
            $arr['appBirthday'] = $this->getBirthday($applicant->certificateNo);//出生日期
        }
        return $arr;
    }

    public function getInsured()
    {
        $insured = $this->visitor->getInsuredVisitor();
        $arr = [
            "insName" => $insured->name,
            "insCertfCde" => $insured->certificateNo,
            "insCertfCls" => DAJIAEnums::$certificateTypeCode[$insured->certificateTypeCode],
            "insCountry" => "1",
            "insProvince" => $insured->provinceCode,
            "insCity" => $insured->cityCode,
            "insCounty" => $insured->areaCode,
            "insClntAddr" => $insured->address,
            "insClntMrk" => DAJIAEnums::$relationTypeCode[$insured->typeCode],
            "insEmail" => $insured->email,
            "insMobile" => $insured->mobile,
            "insExpiredFlag" => "false",
            "insEffectiveDate" => $insured->certificateStartDate,
            "insExpiredDate" => $insured->certificateEndDate,
            "insStreet" => $insured->address
        ];
        if($insured->typeCode == 'R1'){
            $arr['insAge'] = $this->getAge($insured->certificateNo);
            $arr['insBirthday'] = $this->getBirthday($insured->certificateNo);
            $arr['insSex'] = $this->getGenderByIDcard($insured->certificateNo);
        }
        return $arr;
    }

    public function getBusinessInfo()
    {
        $extInfo = $this->extVisitor;
        $arr = [
            "opDpt" => $extInfo->argc['busiOpdpt'] ?? '',//登录机构
            "oprCde" => $extInfo->argc['busiOprCde'] ?? '',//操作员代码
            "dptCde" => $extInfo->argc['busiDptCde'] ?? '',//出单口
            "bsnsTyp" => $extInfo->argc['busiBsnsTyp'] ?? '',//业务来源
            'brkrCde' => $extInfo->argc['busiBrkrCde'] ?? '',
//            "chaSalesId" => "",
            "slsCde" => $extInfo->argc['busiSlsCde'] ?? '',//业务员代码
//            "slsId" => "110101197312010099",
            "recommendCde" => $extInfo->argc['busiRecommendCde'] ?? '',//推荐人代码
            "channelSrc" => $extInfo->argc['noCarChannel'] ?? '',//渠道
            "recSubChannel" => $extInfo->argc['busiRecSubChannel'] ?? '',//推荐子渠道
            "dataSrc" => $extInfo->argc['busiDataSrc'] ?? '',//一级来源
            "dataFlag" => $extInfo->argc['busiDataFlag'] ?? ''//二级来源
        ];
        return $arr;
    }

    public function getProdBaseInfo()
    {
        /**
         * @var NonCarProductVisitor $plan
         */
        $plan = $this->visitor->getNonCarList()[0] ?? [];;
        return [
            "prodNo" => $plan->productCode,
            "feeGeneType" => "0"//默认
        ];

    }

    public function getProdCvrgList()
    {
        $list = [];
        /**
         * @var NonCarProductVisitor $plan
         */
        $plan = $this->visitor->getNonCarList()[0] ?? [];
        /**
         * @var NonCarSubCoveragePrinter $val
         */
        foreach ($plan->subCoverage as $key => $val){
            $list[] = [
                "prodNo" => $plan->productCode,//产品编码
                "seqNo" => intval($key + 1),//序号
//            "cvrgType" => "0",
                "cvrgCde" => $val->subCode,//险别代码
                "cvrgNme" => $val->subName,//险别名称
                "responsisCde" => $val->argc['responsibilityCode'],//责任代码
                "responsisNme" => $val->argc['responsibility'],//责任名称
                "cvrgAmt" => $val->premium,//保额合计
                "cvrgPrm" => round($val->amount * $plan->insuredNum,2),//保费合计/保费小计
                "freeDuty" => $val->argc['taxType'],//应免税
                "rate" => $val->rate,//费率（‰）/基准费率
                "floatCoef" => 100,//折扣系统/浮动系数(%) 目前固定是100
                "tgtQty" => $plan->insuredNum,//数量/人数
                "perAmt" => $plan->premium,//单一标的保额合计
                "perPrm" => $val->premium,//单一标的保费合计/单车保费小计
//                "seatNum" => $this->visitor->getVehicleVisitor()->vehicleSeat,//座位数
//                "carNum" => 1//车辆数
            ];
        }

        return $list;
    }

    public function get0679Tgt()
    {
        return [
            "cTgtTxtFld1" => $this->carKindCode(),//驾驶机动车类别
            "cTgtTxtFld4" => $this->getCarKindType()//驾驶机动车类别次级
        ];
    }

    /**
     * 机动车类别
     * @return string
     * @throws Exception
     */
    private function carKindCode()
    {
        $vehicle = $this->visitor->getVehicleVisitor();
        if($vehicle->carKindCode == '100'){
            //客车
            if($vehicle->useNatureCode == '01'){
                return '00';//非营业客车
            }else{
                return '05';//营业客车
            }
        }else if($vehicle->carKindCode == '200'){
            //货车
            if($vehicle->useNatureCode == '01'){
                return '06';//非营业货车
            }else{
                return '01';//营业货车
            }
        }else{
            throw new Exception("不支持的机动车类别");
        }
    }

    private function getCarKindType()
    {
        $vehicle = $this->visitor->getVehicleVisitor();
        $seat = $vehicle->vehicleSeat;
        if($seat <= 5){
            return '0000';
        }elseif( $seat <= 7){
            return '0001';
        }elseif( $seat <= 9){
            return '0002';
        }elseif( $seat <= 22){
            return '0003';
        }else{
            throw new Exception("不支持的机动车类别次级");
        }
    }

    public function get0684Tgt()
    {
        $res = $this->get0679Tgt();
        $arr = [
            'cTgtTxtFld1' => $res['cTgtTxtFld1'],//驾驶机动车类别
            'cTgtTxtFld4' => $res['cTgtTxtFld4'],//驾驶机动车类别次级
        ];
        /**
         * @var NonCarProductVisitor $plan
         */
        $plan = $this->visitor->getNonCarList()[0] ?? [];
        /**
         * @var NonCarSubCoveragePrinter $val
         */
        foreach ($plan->subCoverage as $key => $val){
            if($val->subCode == '081817'){
                $arr['cTgtTxtFld11'] = '463001';//房屋建筑结构
                $arr['cTgtTxtFld12'] = '1';//国家
                $arr['cTgtTxtFld13'] = $this->visitor->getApplicantVisitor()->provinceCode;//省
                $arr['cTgtTxtFld14'] = $this->visitor->getApplicantVisitor()->cityCode;//市
                $arr['cTgtTxtFld15'] = $this->visitor->getApplicantVisitor()->areaCode;//县/区
                $arr['cTgtTxtFld16'] = $this->visitor->getApplicantVisitor()->address;//街道
                $arr['cTgtTxtFld17'] = $this->visitor->getApplicantVisitor()->address;//家庭财产标的地址
            }
        }

        return $arr;
    }

    public function get0679TgtList()
    {
        /**
         * @var NonCarProductVisitor $plan
         */
        $plan = $this->visitor->getNonCarList()[0] ?? [];
        $vehicle = $this->visitor->getVehicleVisitor();
        $info = [ [
            "nSeqNo" => 1,//序号
            "cResevFld6" => DAJIAEnums::$useNatureCode[$vehicle->useNatureCode] ?? '02',//车辆使用性质 默认非运营
            "cResevFld5" => $vehicle->vehicleSeat,//核定座位数
            "cResevFld4" => $vehicle->vin,//车架号
            "cResevFld3" => $vehicle->engineNo,//发动机号
            "cResevFld2" => $vehicle->vehicleModel,//厂牌型号
            "cResevFld1" => $vehicle->licenseNo//车牌号码
        ]];
        return $info;
    }

    public function get0684TgtList()
    {
        return $this->get0679TgtList();
    }

    /**
     * 通过身份证获取性别
     * @param $idcard
     * @return int
     * @throws Exception
     */
    private function getGenderByIDcard($idCard){
        if(strlen($idCard) != 18){
            throw new Exception("身份证位数不合法");
        }
        $gender = intval(substr($idCard,16,1)) % 2;
        return $gender ? '3A05001' : '3A05002';
    }

    private function getBirthday($idCard)
    {
        if(strlen($idCard) != 18){
            throw new Exception("身份证位数不合法");
        }
        return substr($idCard,6,4).'-'.substr($idCard,10,2).'-'.substr($idCard,12,2);
    }

    private function getAge($idCard)
    {
        $birthdate = substr($idCard, 6, 8);
        $birthYear = substr($birthdate, 0, 4);
        $birthMonth = substr($birthdate, 4, 2);
        $birthDay = substr($birthdate, 6, 2);

        $currentYear = date('Y');
        $currentMonth = date('m');
        $currentDay = date('d');

        $age = $currentYear - $birthYear;
        if ($currentMonth < $birthMonth || ($currentMonth == $birthMonth && $currentDay < $birthDay)) {
            $age--; // 未过生日，年龄减一
        }

        return $age;
    }

}
